package com.itisyue.controller;

import com.alibaba.fastjson.JSONObject;
import com.itisyue.common.LoginRequest;
import com.itisyue.common.LoginResponse;
import com.itisyue.common.RefreshRequest;
import com.itisyue.common.ResponseResult;
import com.itisyue.enums.ResponseCodeEnum;
import com.itisyue.utils.JWTUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
public class TestController {
    @Value("${secretKey:123456}")
    private String secretKey;

    @Value("${server.port}")
    private String serverPort;

    @RequestMapping("/test")
    @ResponseBody
    public JSONObject test(){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("serverPort", serverPort);
        return jsonObject;
    }

    @RequestMapping("/setSession")
    @ResponseBody
    public JSONObject setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("service", "service1");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("serverPort", serverPort);
        jsonObject.put("setSession service", "service1");
        return jsonObject;
    }

    @RequestMapping("/getSession")
    @ResponseBody
    public JSONObject getSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        Object service = session.getAttribute("service");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("serverPort", serverPort);
        jsonObject.put("getSession ", service);
        return jsonObject;
    }

    @PostMapping("/upload")
    @ResponseBody
    public JSONObject upload(@RequestParam("file") MultipartFile file, String id, HttpServletRequest request){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("size", file.getSize());
        System.out.println("计算大小完毕");
        return jsonObject;
    }

    @GetMapping("/redirect/{id}")
    public void redirect(@PathVariable("id") String id, HttpServletResponse resp) throws IOException {
        String redirectUri = "http://127.0.0.1/jiaju/index2.html";
        resp.sendRedirect(redirectUri);
    }


    /**
     * 登录
     */
    @PostMapping("/login")
    public ResponseResult login(@RequestBody @Validated LoginRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseResult.error(ResponseCodeEnum.PARAMETER_ILLEGAL.getCode(),   ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
        }

        String username = request.getUsername();
        String password = request.getPassword();
        //  假设查询到用户ID是1001
        String userId = "1001";
        if ("hello".equals(username) && "world".equals(password)) {
            //  生成Token
            String token = JWTUtil.createJwt(userId, secretKey);

            //  生成刷新Token
            String refreshToken = UUID.randomUUID().toString().replace("-", "");

            //  放入缓存
            //HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();
            //            hashOperations.put(refreshToken, "token", token);
            //            hashOperations.put(refreshToken, "user", username);
            //            stringRedisTemplate.expire(refreshToken, JWTUtil.TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);

            /**
             * 如果可以允许用户退出后token如果在有效期内仍然可以使用的话，那么就不需要存Redis
             * 因为，token要跟用户做关联的话，就必须得每次都带一个用户标识，
             * 那么校验token实际上就变成了校验token和用户标识的关联关系是否正确，且token是否有效
             */

            //            String key = MD5Encoder.encode(userId.getBytes());

            String key = userId;
            //hashOperations.put(key, "token", token);
            //hashOperations.put(key, "refreshToken", refreshToken);
            //stringRedisTemplate.expire(key, JWTUtil.TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);

            LoginResponse loginResponse = new LoginResponse();
            loginResponse.setToken(token);
            loginResponse.setRefreshToken(refreshToken);
            loginResponse.setUserId(userId);

            return ResponseResult.success(loginResponse);
        }

        return ResponseResult.error(ResponseCodeEnum.LOGIN_ERROR.getCode(), ResponseCodeEnum.LOGIN_ERROR.getMessage());
    }

    /**
     * 退出
     */
    @GetMapping("/logout")
    public ResponseResult logout(@RequestParam("userId") String userId) {
        //HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();
        //String key = userId;
        //hashOperations.delete(key);
        return ResponseResult.success();
    }

    /**
     * 刷新Token
     */
    @PostMapping("/refreshToken")
    public ResponseResult refreshToken(@RequestBody @Validated RefreshRequest request, BindingResult bindingResult) {
        String userId = request.getUserId();
        String refreshToken = request.getRefreshToken();
//        HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();
//        String key = userId;
//        String originalRefreshToken = hashOperations.get(key, "refreshToken");
//        if (StringUtils.isBlank(originalRefreshToken) || !originalRefreshToken.equals(refreshToken)) {
//            return ResponseResult.error(ResponseCodeEnum.REFRESH_TOKEN_INVALID.getCode(), ResponseCodeEnum.REFRESH_TOKEN_INVALID.getMessage());
//        }
//
//        //  生成新token
        String newToken = JWTUtil.createJwt(userId, secretKey);
//        hashOperations.put(key, "token", newToken);
//        stringRedisTemplate.expire(userId, JWTUtil.TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);

        return ResponseResult.success(newToken);
    }
}
